#import "BWLayerSet.h"
#import "BWLayer.h"

@implementation BWLayerSet

+ (void) initalize
{
    [super initialize];

    [BWLayerSet setVersion: 1];

} // initialize


// --------------------------------------------------
// bindings jazz

- (NSArray *) layers
{
    return (layers);
} // layers


- (void) insertObject: (id) obj
      inLayersAtIndex: (unsigned) index
{
    [layers insertObject: obj  atIndex: index];
} // insertObjectInLayers


- (void) removeObjectFromLayersAtIndex: (unsigned) index
{
    [layers removeObjectAtIndex: index];
} // removeObjectFromLayersAtIndex


// --------------------------------------------------

- (id) init
{
    if (self = [super init]) {
        layers = [[NSMutableArray alloc] init];
    }

    return (self);

} // init


- (void) dealloc
{
    [layers release];

    [super dealloc];

} // dealloc


// and post BWLayer_ChangeNotification when doing stuff?

- (void) addLayer: (BWLayer *) layer
{
    [self addLayer: layer
          atIndex: [layers count]];
} // addLayer


- (void) hookUpObservation: (BWLayer *) layer
{
    // post layer add notification, or something
    [layer addObserver: self
           forKeyPath: @"visible"
           options: nil
           context: NULL];

    [layer addObserver: self
           forKeyPath: @"active"
           options: nil
           context: NULL];

    [layer addObserver: self
           forKeyPath: @"layerChange"
           options: nil
           context: NULL];

} // hookUpObservation


- (void) addLayer: (BWLayer *) layer
          atIndex: (int) index
{
    [self insertObject: layer
          inLayersAtIndex: index];

    [self hookUpObservation: layer];

} // addLayer


- (void) removeLayerAtIndex: (int) index
{
    [self willChangeValueForKey: @"setChange"];
    [self removeObjectFromLayersAtIndex: index];
    [self didChangeValueForKey: @"setChange"];

} // removeLayerAtIndex


- (BOOL) setChange
{
    return (YES);
} // setChange


- (int) count
{
    return ([layers count]);
} // count


- (BWLayer *) layerAtIndex: (int) index
{
    return ([layers objectAtIndex: index]);
} // layerAtIndex


- (NSEnumerator *) layerEnumerator
{
    return ([layers objectEnumerator]);
} // layerEnumerator


- (NSEnumerator *) reverseLayerEnumerator
{
    return ([layers reverseObjectEnumerator]);
} // reverseLayerEnumerator






- (void) observeValueForKeyPath: (NSString *) kp
                       ofObject: (id) object
                         change: (NSDictionary *) change
                        context: (void *) context
{
    if ([kp isEqualToString: @"visible"]
        || [kp isEqualToString: @"active"]) {
        [self willChangeValueForKey: @"setChange"];
        [self didChangeValueForKey: @"setChange"];
    }

    if ([kp isEqualToString: @"layerChange"]) {
        [self willChangeValueForKey: @"setChange"];
        [self didChangeValueForKey: @"setChange"];
    }

} // observeValueForKeyPath


- (void) showAllLayers
{
    NSEnumerator *enumerator = [self layerEnumerator];
    
    BWLayer *layer;
    while (layer = [enumerator nextObject]) {
        [layer setVisible: YES];
    }

} // showAllLayers


- (void) soloLayerAtIndex: (int) index
{
    NSEnumerator *enumerator = [self layerEnumerator];
    
    BWLayer *layer;
    while (layer = [enumerator nextObject]) {
        [layer setVisible: NO];
    }

    layer = [self layerAtIndex: index];
    [layer setVisible: YES];

} // soloLayerAtIndex


- (int) countOfLayersOfKind: (BWLayerKind) kind
{
    int count = 0;

    NSEnumerator *enumerator = [self layerEnumerator];
    
    BWLayer *layer;
    while (layer = [enumerator nextObject]) {
        if ([layer layerKind] == kind) {
            count++;
        }
    }

    return (count);
    
} // countOfLayersOfKind



- (NSEnumerator *) activeLayerEnumeratorForKind: (BWLayerKind) kind
{
    NSMutableArray *array = [[NSMutableArray alloc] init];

    NSEnumerator *enumerator = [self layerEnumerator];
    
    BWLayer *layer;
    while (layer = [enumerator nextObject]) {
        if ([layer layerKind] == kind) {
            if ([layer active]) {
                [array addObject: layer];
            }
        }
    }

    [array autorelease];

    return ([array objectEnumerator]);

} // activeLayerEnumeratorForKind



- (void) encodeWithCoder: (NSCoder *) coder
{
    [coder encodeObject: layers];
    
} // encodeWithCoder


- (id) initWithCoder: (NSCoder *) coder
{
    if (self = [super init]) {
        [layers release];
        layers = [coder decodeObject];
        [layers retain];

        NSEnumerator *enumerator = [layers objectEnumerator];
        
        BWLayer *layer;
        while (layer = [enumerator nextObject]) {
            [self hookUpObservation: layer];
        }
    }

    return (self);

} // initWithCoder


- (void) setGeometry: (BWGridGeometry *) geometry
{
    NSEnumerator *enumerator = [layers objectEnumerator];

    BWLayer *layer;
    while (layer = [enumerator nextObject]) {
        [layer setGeometry: geometry];
    }

} // setGeometry


@end // BWLayerSet


